package com.gillion.grape.fros.ui.commands;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.java.amateras.uml.classdiagram.model.Argument;
import net.java.amateras.uml.classdiagram.model.AssociationModel;
import net.java.amateras.uml.classdiagram.model.AttributeModel;
import net.java.amateras.uml.classdiagram.model.ClassModel;
import net.java.amateras.uml.classdiagram.model.InterfaceModel;
import net.java.amateras.uml.classdiagram.model.OperationModel;
import net.java.amateras.uml.classdiagram.model.RelationType;
import net.java.amateras.uml.model.AbstractUMLEntityModel;
import net.java.amateras.uml.model.RootModel;
import net.java.amateras.uml.properties.ManyToOneRelation;
import net.java.amateras.uml.properties.OneToManyRelation;

import org.dom4j.DocumentException;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;

import com.gillion.grape.core.utils.PU;
import com.gillion.grape.core.utils.ProjectConfig;
import com.gillion.grape.core.utils.SU;
import com.gillion.grape.core.utils.Utils;
import com.gillion.grape.fros.core.data.TypeEntry;
import com.gillion.grape.fros.core.meta.GFAClassType;
import com.gillion.grape.fros.core.meta.FrosClass;
import com.gillion.grape.fros.core.meta.FrosMethod;
import com.gillion.grape.fros.core.meta.FrosProperty;
import com.gillion.grape.fros.ui.Entity2ERUtils;
import com.gillion.grape.fros.ui.Platform;
import com.gillion.grape.fros.ui.util.FU;
import com.gillion.grape.fros.ui.util.FileUtil;
import com.gillion.grape.fros.ui.util.IOUtils;
import com.gillion.grape.fros.ui.util.ReplaceUtil;
import com.gillion.grape.gencode.JETContext;
import com.gillion.grape.gencode.JETContextHelper;
import com.gillion.grape.gencode.wef.GenGFACodeAdapter;
import com.gillion.grape.meta.XmlModel;
import com.gillion.grape.technology.ui.commands.IModel2Code;
import com.gillion.grape.technology.ui.commands.Model2Code;

public class GFAModel2FrosCode extends PSM2Code{
	
	public GFAModel2FrosCode(List<AbstractUMLEntityModel> list){
		this.list=list;  
	}
	private RootModel rootModel;
	private List<AbstractUMLEntityModel>list;
	private IModel2Code model2code = new Model2Code();
	private String whichPlugin = "com.gillion.grape.fros";

	
	public void genModelFiles(IProject project,ProjectConfig projectConfig,FrosClass oneGClass,String moduleName,List<Map<String, Object>> properties_validate_exist,List<Map<String, Object>> properties_validate_unique,String label) {
		List<AbstractUMLEntityModel> umlModels = list;
		int modelSize = umlModels.size();
		for (int i = 0; i < modelSize; i++) {
			if (!(umlModels.get(i) instanceof ClassModel)) {
				continue; // 只对类模型进行处理
			}
			// 初始化实体类
			ClassModel gfaEntityClass = (ClassModel)umlModels.get(i);
			if ((gfaEntityClass.getSimpleName()).equals(oneGClass.getName())) {
				IFile entityCode = project.getFile("/src/"
						+ projectConfig.getNameSpace().replaceAll("\\.", "/") + "/" + moduleName  
						+ "/model/" + oneGClass.getName() + "Model.java");
				JETContext context = JETContextHelper.newJETContextHelper(project, moduleName, projectConfig);
				Map<String, Object> param = gfaEntity2XmlModel(oneGClass);
				InputStream content = GenGFACodeAdapter.mergeJavaCode4Stream(param, projectConfig.getEntityTpl(), 0, context, entityCode,whichPlugin);
				if (content == null) {
					return;
				}
				//wefs
				FileUtil.writeFile(content, entityCode);
				
				if (!oneGClass.isVoEntity()){
					// 生成hbm文件(判断是否是视图实体)
					if (!oneGClass.isViewEntity()) {
						String templatePath = projectConfig.getEntityHbmTpl();
						if (oneGClass.getHbmtemplate() != null && oneGClass.getHbmtemplate().length() > 0){
							if (oneGClass.getHbmtemplate().indexOf("oneGClass.getHbmtemplate()") < 0){
								templatePath = oneGClass.getHbmtemplate();
							}
						}
						String hbmContent = GenGFACodeAdapter.genJavaCode(gfaEntity2hbmParam(oneGClass), templatePath, 0, context,whichPlugin);
						if (hbmContent == null) {
							return;
						}
						//wef
						IFile hbmFile = project.getFile("/src/"
								+ projectConfig.getNameSpace().replaceAll("\\.", "/") + "/" + moduleName 
								+ "/hbm/" + oneGClass.getName() + ".hbm.xml");
						if (hbmFile.exists()){
							String existHbmCode = FU.readStringFromFile(hbmFile.getLocation().toString());
							hbmContent = ReplaceUtil.replace(hbmContent, existHbmCode, ReplaceUtil.PATTERN_TYPE_XML);
						}
						FileUtil.writeFile(IOUtils.string2InputStream(hbmContent), hbmFile);
					} else {
						InputStream hbmContent = GenGFACodeAdapter.genJavaCode4Stream(gfaEntity2hbmParam(oneGClass), projectConfig.getEntityHbmViewTpl(), 0, context,whichPlugin);
						if (hbmContent == null) {
							return;
						}
						//wef
						IFile hbmFile = project.getFile("/src/"
								+ projectConfig.getNameSpace().replaceAll("\\.", "/") + "/" + moduleName 
								+ "/hbm/" + oneGClass.getName() + ".hbm.xml");
						FileUtil.writeFile(hbmContent, hbmFile);
					}
				}
			}
				
				// 生成验证properties文件
//				properties_validate_exist.add(gfaEntity2XmlModel(oneGClass));
//				properties_validate_unique.add(gfaEntity2XmlModel(oneGClass));
			}
		}
	
	/**
	 * Domain转模板参数
	 * 
	 * @param gclass
	 * @return
	 * 
	 * @author meichenhui
	 * @since 2011-9-7
	 * 
	 */
	private Map<String, Object> gfaDomain2XmlModel(FrosClass gclass) {
		// 读取工程配置
		ProjectConfig projectConfig = PU.readProjectDesc();
		
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("optimistic", "true");
		params.put("project_name",projectConfig.getNameSpace());
		params.put("module_code", this.getModuleName());
		params.put("entity_name", gclass.getName());
		params.put("table_name", gclass.getName().toUpperCase());
		// property_list.property
		List<Map<String, Object>> properties = new ArrayList<Map<String, Object>>();
		List<FrosProperty> gProperties = gclass.getProperties();
		for (FrosProperty oneGProperty : gProperties) {
			Map<String, Object> property = new HashMap<String, Object>();
			property.put("property_name", oneGProperty.getName());
			property.put("physical_name", Entity2ERUtils.logicalName2PhysicalName(oneGProperty.getName()));
			property.put("property_type", oneGProperty.getType());
			property.put("physical_type", Entity2ERUtils.javaType2OracleType(oneGProperty.getType()));
			property.put("type", "kk");
			property.put("domain_type", oneGProperty.getDomainType());
			property.put("not_null", "false");
			property.put("unique", "false");
			property.put("vertical_extend_field", oneGProperty.isVerticalExtendField() ? "true" : "false");
			if (Entity2ERUtils.genPrimaryKeyProperty(gclass.getName()).equals(oneGProperty.getName())) {
				property.put("primary_key", "true");
				property.put("type", "id");
				property.put("not_null", "true");
				property.put("unique", "true");
			}
			properties.add(property);
		}
		params.put("property_list.property", properties);
		return params;
	}

	private Map<String, Object> gfaEntity2XmlModel(FrosClass gclass) {
		// 读取工程配置
		ProjectConfig projectConfig = PU.readProjectDesc();
		
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("project_name", projectConfig.getNameSpace());
		params.put("module_code",  this.getModuleName());
		params.put("entity_name", gclass.getName());
		params.put("vertical_extend", gclass.isVerticalExtend() ? "true" : "false");
		if(gclass.getEnglish()!=null && gclass.getEnglish().length()>0)
		{
		params.put("i18n_en", gclass.getEnglish());
		}else
		{
		params.put("i18n_en", gclass.getName());
		}
		params.put("i18n_cn", gclass.getSimplifiedChinese());
		params.put("stuffix", gclass.getSuffix());

		// property_list.property
		List<Map<String, Object>> properties = new ArrayList<Map<String, Object>>();
		List<FrosProperty> gProperties = gclass.getProperties();
		for (FrosProperty oneGProperty : gProperties) {
			Map<String, Object> property = new HashMap<String, Object>();
			property.put("property_name", oneGProperty.getName());
			property.put("property_short_type", oneGProperty.getType());
			property.put("property_type", oneGProperty.getType());
			property.put("type", oneGProperty.getRelation());
			if(oneGProperty.getEnglish()!=null && oneGProperty.getEnglish().length()>0)
			{
				property.put("i18n_en", oneGProperty.getEnglish());
			}else
			{
				property.put("i18n_en", oneGProperty.getName());
			}
			property.put("i18n_cs", oneGProperty.getSimplifiedChinese());
			property.put("validate_exist", oneGProperty.isValidateExist());
			property.put("validate_unique", oneGProperty.isValidateUnique() ? "true" : "false");
			property.put("vertical_extend_field", oneGProperty.isVerticalExtendField() ? "true" : "false");

			properties.add(property);
		}
		params.put("property_list.property", properties);
		params.put("extends", "BaseObject");
		params.put("ONE2MANYEXT",gclass.getOneToManyRelationExtends());
		params.put("MANY2ONEEXT",gclass.getManyToOneRelationExtends());
		params.put("cache", gclass.isCache() ? "true" : "flase");
		return params;
	}
	
	private Map<String, Object> gfaEntity2hbmParam(FrosClass gclass) {
		// 读取工程配置
		ProjectConfig projectConfig = PU.readProjectDesc();
		
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("optimisticLock", gclass.getOptimisticLock().getName());
		params.put("project_name", projectConfig.getNameSpace());
		params.put("module_code",  this.getModuleName());
		params.put("entity_name", gclass.getName());
		params.put("custom_table_name", gclass.getCustomTableName());
		params.put("table_name", Entity2ERUtils.logicalName2PhysicalName(gclass.getName()).toUpperCase());
		params.put("generator", gclass.getGenerator().getName());
		// property_list.property
		List<Map<String, Object>> properties = new ArrayList<Map<String, Object>>();
		List<FrosProperty> gProperties = gclass.getProperties();
		for (FrosProperty oneGProperty : gProperties) {
			Map<String, Object> property = new HashMap<String, Object>();
			// 先从java类型转换到模型类型
			TypeEntry physical_type  = new TypeEntry(oneGProperty.getType() + oneGProperty.getTypeLenExpression(), Platform.JAVA, Platform.MODEL);
			
			if(projectConfig.getTypeEntry().equalsIgnoreCase("sqlserver")){//add by taiyuan   从模型类型转换到数据库类型判断
		    	physical_type.setTargetPlatform(Platform.SQLSERVER); 
			}else{
				physical_type.setTargetPlatform(Platform.ORACLE); 
			}
			
			// 先从java类型转换到模型类型
			TypeEntry property_type = new TypeEntry(oneGProperty.getType() + oneGProperty.getTypeLenExpression(), Platform.JAVA, Platform.MODEL);
			property_type.setTargetPlatform(Platform.HIBERNATE_HBM); // 从模型类型转换到hibernate类型
			property.put("property_name", oneGProperty.getName());
			property.put("physical_name", Entity2ERUtils.logicalName2PhysicalName(oneGProperty.getName()));

			property.put("property_type", property_type.getDataTypeName());
			property.put("physical_type", physical_type.getDataTypeName() + oneGProperty.getTypeLenExpression());
			property.put("type", "property");
			property.put("not_null", "false");
			property.put("unique", "false");
			property.put("custom_property_name", oneGProperty.getCustomPropertyName());
			property.put("custom_table_name", gclass.getCustomTableName());
			property.put("vertical_extend_field", oneGProperty.isVerticalExtendField() ? "true" : "false");

			if (oneGProperty.getRelation().equals(RelationType.ONE2MANY.name())) {
				property.put("lazy", oneGProperty.getLazyO2MType());
				property.put("type", oneGProperty.getRelation());
				property.put("cascade", oneGProperty.getCascade());
				//一对多
				property.put("physical_name", Entity2ERUtils.logicalName2PhysicalName4One2Many(oneGProperty.getName()));
			}
			if (oneGProperty.getRelation().equals(RelationType.ONE2ONE.name())) {
				property.put("lazy", oneGProperty.getLazyO2MType());
				property.put("type", oneGProperty.getRelation());
				property.put("cascade", oneGProperty.getCascade());
				//一对多
				property.put("physical_name", Entity2ERUtils.logicalName2PhysicalName4One2Many(oneGProperty.getName()));
			}
			if (oneGProperty.getRelation().equals(RelationType.ONE2ONESUB.name())) {
				property.put("lazy", oneGProperty.getLazyO2MType());
				property.put("type", oneGProperty.getRelation());
				property.put("cascade", oneGProperty.getCascade());
				//一对多
				property.put("physical_name", Entity2ERUtils.logicalName2PhysicalName4One2Many(oneGProperty.getName()));
			}
			if (oneGProperty.getRelation().equals(RelationType.MANY2ONE.name())) {
				property.put("lazy", oneGProperty.getLazyM2OType());
				property.put("type", oneGProperty.getRelation());
				property.put("cascade", oneGProperty.getCascade());
			}
			// 实体或视图ID
			if (Entity2ERUtils.genPrimaryKeyProperty(gclass.getName()).equals(oneGProperty.getName())
					|| oneGProperty.isViewIdFlag()) {
				property.put("primary_key", "true");
				property.put("type", "id");
				property.put("not_null", "true");
				property.put("unique", "true");
			}

			if ("recordVersion".equals(oneGProperty.getName())) {
				property.put("type", "recordVersion");
			}
			properties.add(property);
		}
		params.put("property_list.property", properties);
		params.put("ONE2MANYEXT",gclass.getOneToManyRelationExtends());
		params.put("MANY2ONEEXT",gclass.getManyToOneRelationExtends());
		params.put("cache", gclass.isCache() ? "true" : "false");
		return params;
	}

	@Override
	public void serializeTransformedModel(String label) {

		// 模型转换
		List<FrosClass> classes = (List<FrosClass>) getGClasses();

		// Spring Config List
		List<XmlModel> springConfiglist = new ArrayList<XmlModel>();
		
		// Dwr Config List
		List<XmlModel> dwrConfiglist = new ArrayList<XmlModel>();

		List<Map<String, Object>> properties_validate_exist = new ArrayList<Map<String, Object>>();
		List<Map<String, Object>> properties_validate_unique = new ArrayList<Map<String, Object>>();

		// 读取工程配置
		ProjectConfig projectConfig = PU.readProjectDesc();
		IProject project =Utils.getCurrentProject();
		IProject projectCustom = Utils.getCurrentProject();
					
		 //begin add by taiyuan 20120718
		if(getRootModel().getNewProjectName()!=null&&getRootModel().getNewProjectName().trim().length()>0){
			projectCustom = ResourcesPlugin.getWorkspace().getRoot().getProject(getRootModel().getNewProjectName());
		}
         //end add by taiyuan 20120718
		
		// 3.获取模块名
		String moduleName = Utils.getCurrentModule();
		
		// 模板文件路径
		for (FrosClass oneGClass : classes) {
			if("生成fros-实体".equals(label)){
				if (oneGClass.getGfaType().equals(GFAClassType.Entity)) {
					genModelFiles(project,projectConfig,oneGClass,moduleName,properties_validate_exist,properties_validate_unique,label);
				}
//				if (oneGClass.getGfaType().equals(GFAClassType.EntityDomain) && !oneGClass.isVoEntity()) {
//					// domain
//					genDomainFiles(projectConfig, project, moduleName, oneGClass);
//				}
			}
			if("生成fros-Servicef".equals(label)){
				if (oneGClass.getGfaType().equals(GFAClassType.Service) && !oneGClass.isViewEntity() && !oneGClass.isVoEntity()) {
					genServiceInterfaceFiles(projectCustom,projectConfig,oneGClass,moduleName);
				}
				if (oneGClass.getGfaType().equals(GFAClassType.ServiceImpl) && !oneGClass.isViewEntity() && !oneGClass.isVoEntity()) {
					genServiceImplFiles(projectCustom,projectConfig,oneGClass,moduleName,springConfiglist,dwrConfiglist);
				}
			}
		}

		if("生成fros-实体f".equals(label)){
		// 生成validate_exist Properties 文件
			if (properties_validate_exist.size() > 0) {
				genValidateExistConfig(properties_validate_exist, projectConfig,
					projectCustom, moduleName);
			}
			
		// 生成 validate_unique Properties 文件
		if (properties_validate_unique.size() > 0) {
			genValidateUniqueConfig(properties_validate_unique, projectConfig,
				projectCustom, moduleName);
			}
		}
		if("生成fros-Servicef".equals(label)){
		// 生成Spring Config
			if (springConfiglist.size() > 0) {
				model2code.genSpringConfig(springConfiglist, projectCustom, moduleName,projectConfig,whichPlugin);
			}
		
		
		// 生成dwr Config
			if (dwrConfiglist.size() > 0) {
				model2code.genDwrConfig(dwrConfiglist, projectCustom, moduleName,projectConfig,whichPlugin);
			}
		}
		genProperties(label);
	}
	
	public void genProperties(String label) {
		
		// 读取工程配置
		ProjectConfig projectConfig = PU.readProjectDesc();
		// 获取工程
		IProject project = Utils.getCurrentProject();
		
		// 获取模块名
		String moduleName = Utils.getCurrentModule();

		// 模型转换
		List<FrosClass> classes = (List<FrosClass>) getGClasses();
		Map<IFile, InputStream> codes = new HashMap<IFile, InputStream>();

		List<Map<String, Object>> i18nParam = new ArrayList<Map<String, Object>>();

		// 模板文件路径
		for (FrosClass oneGClass : classes) {
			if (!oneGClass.getGfaType().equals(GFAClassType.Entity)) {
				continue;
			}
			// 生成properties文件参数
			Map<String, Object> param = gfaEntity2XmlModel(oneGClass); 
			i18nParam.add(param);
		}

		// 生成Properties 默认文件
		if("生成fros-实体f".equals(label)){
			if (i18nParam.size() > 0) {
				IFile modulePropertyFile = project.getFile("/src/resource/i18n/" + moduleName + ".properties");
				JETContext context = JETContextHelper.newJETContextHelper(project, moduleName, projectConfig);
				InputStream propertiesResult = GenGFACodeAdapter.mergeProperties4Stream(i18nParam, projectConfig.getPropertiesTpl(), 0, context, modulePropertyFile,whichPlugin);
				if (propertiesResult != null){
					FileUtil.writeFile(propertiesResult, modulePropertyFile);
				}
			}
		
		// 生成Properties _zh_CN文件
			if (i18nParam.size() > 0) {
				IFile chineseFile = project.getFile("/src/resource/i18n/" + moduleName + "_zh_CN.properties");
				JETContext context = JETContextHelper.newJETContextHelper(project, moduleName, projectConfig);
				InputStream chineseResult = GenGFACodeAdapter.mergeProperties4Stream(i18nParam, projectConfig.getPropertiesZhCNTpl(), 0, context, chineseFile,whichPlugin);
				if (chineseResult != null){
					FileUtil.writeFile(chineseResult, chineseFile);
				}
			}
		
		// 生成Properties _en文件
			if (i18nParam.size() > 0) {
				JETContext context = JETContextHelper.newJETContextHelper(project, moduleName, projectConfig);
				IFile enFile = project.getFile("/src/resource/i18n/" + moduleName + "_en.properties");
				InputStream enResult = GenGFACodeAdapter.mergeProperties4Stream(i18nParam, projectConfig.getPropertiesEnTpl(), 0, context,enFile,whichPlugin);
				if (enResult != null){
					FileUtil.writeFile(enResult, enFile);
				}
			}
		}
		if("生成fros-Servicef".equals(label)){
		model2code.addConfig(moduleName, projectConfig, getRootModel(),whichPlugin);
		}
	}
	
	private Object getGClasses() {
		List<FrosClass> classes = new ArrayList<FrosClass>();
		List<?> umlModels = getRootModel().getChildren();
		for (Object oneUMLModel : umlModels) {
			if (oneUMLModel instanceof ClassModel) {
				FrosClass classModel = umlModel2GModel((ClassModel) oneUMLModel);
				classes.add(classModel);
				continue;
			}
			if (oneUMLModel instanceof InterfaceModel) {
				FrosClass gInterface = interfaceModel2GInterface((InterfaceModel) oneUMLModel);
				classes.add(gInterface);
				continue;
			}
		}
		return classes;
	}
	
	protected RootModel getRootModel() {
		if (rootModel == null) {
			rootModel = Entity2ERUtils.deserializUMLDiagram(getPSMModelFileInput()); // UML图形反序列化为图形对象
		}
		return rootModel;
	}
	
	private void genDomainFiles(ProjectConfig projectConfig, IProject project,	String moduleName, FrosClass oneGClass) {
		List<AbstractUMLEntityModel> umlModels =list;
		int modelSize = umlModels.size();
		for (int i = 0; i < modelSize; i++) {
			if (!(umlModels.get(i) instanceof ClassModel)) {
				continue; // 只对类模型进行处理
			}
			// 初始化实体类
			ClassModel gfaEntityClass = (ClassModel)umlModels.get(i);
			if ((gfaEntityClass.getSimpleName()).equals(oneGClass.getName().substring(0,
					oneGClass.getName().length() - 6))) {
				String templatePath = oneGClass.getDeltemplate();
				JETContext serviceImplContext = JETContextHelper.newJETContextHelper(project, moduleName, projectConfig);
				IFile file = project.getFile("/src/"
						+ projectConfig.getNameSpace().replaceAll("\\.", "/") + "/" + moduleName  
						+ "/entity/domain/" + oneGClass.getName() + ".java");
				JETContext context = JETContextHelper.newJETContextHelper(project, moduleName, projectConfig);
				Map<String,Object> param = gfaDomain2XmlModel(oneGClass);
				InputStream content = GenGFACodeAdapter.genJavaCode4Stream(param, projectConfig.getEntityDomainTpl(), 0, context,whichPlugin);
				if (content != null){
					FileUtil.writeFile(content, file);
				}
		    }
		}
		}
	
	private void genServiceInterfaceFiles(IProject project,ProjectConfig projectConfig,FrosClass oneGClass,String moduleName){
		XmlModel xmlModel = new XmlModel();

		xmlModel.set("entity_name", oneGClass.getName().substring(0, oneGClass.getName().length() - 7));
		xmlModel.set("package_name", projectConfig.getNameSpace() +"." + moduleName + ".service");
		xmlModel.set("entity_path", projectConfig.getNameSpace() +"." + moduleName);
		xmlModel.set("service_name", oneGClass.getName());
		if (oneGClass.getParentService() == null || oneGClass.getParentService().length() == 0){
			xmlModel.set("baseservice", "baseService");
		} else {
			xmlModel.set("baseservice", oneGClass.getParentService());
		}
		//
		List<String> lstChildEntityName = new ArrayList<String>();
		List<Map<String, Object>> lstChildEntity = new ArrayList<Map<String, Object>>();
		Map<String, Object> mapChildEntity = new HashMap<String, Object>();

		//
		List<String> lstParentEntityName = new ArrayList<String>();
		List<Map<String, Object>> lstParentEntity = new ArrayList<Map<String, Object>>();
		Map<String, Object> mapParentEntity = new HashMap<String, Object>();

		List umlModels = list;
		int modelSize = umlModels.size();
		
		for (int i = 0; i < modelSize; i++) {
			if (!(umlModels.get(i) instanceof ClassModel)) {
				continue; // 只对类模型进行处理
			}
			// 初始化实体类
			ClassModel gfaEntityClass = (ClassModel) umlModels.get(i);
			if ((gfaEntityClass.getSimpleName()).equals(oneGClass.getName().substring(0,
					oneGClass.getName().length() - 7))) {
				xmlModel.set("vertical_extend", gfaEntityClass.isVerticalExtend() ? "true" : "false");
				// source
				List<AssociationModel> sourceAssociations = (List<AssociationModel>) gfaEntityClass
						.getModelSourceConnections();
				for (AssociationModel oneAssociation : sourceAssociations) {
					if ("1".equals(oneAssociation.getFromMultiplicity())) { // 主表
						ClassModel child = (ClassModel) oneAssociation.getTarget();
						lstChildEntityName.add(child.getSimpleName());
					}
					if ("*".equals(oneAssociation.getFromMultiplicity())) { // 子表
						ClassModel parent = (ClassModel) oneAssociation.getTarget();
						lstParentEntityName.add(parent.getSimpleName());
					}
				}

				// target
				List<AssociationModel> targetAssociations = (List<AssociationModel>) gfaEntityClass
						.getModelTargetConnections();
				for (AssociationModel oneAssociation : targetAssociations) {
					if ("*".equals(oneAssociation.getToMultiplicity())) { // 子表
						ClassModel parent = (ClassModel) oneAssociation.getSource();
						lstParentEntityName.add(parent.getSimpleName());
					}
					if ("1".equals(oneAssociation.getToMultiplicity())) { // 主表
						ClassModel child = (ClassModel) oneAssociation.getSource();
						lstChildEntityName.add(child.getSimpleName());
					}
				}
				if (lstChildEntityName != null) {
					for (String childEntityName : lstChildEntityName) {
						Map<String, Object> mapRefService = new HashMap<String, Object>();
						mapRefService.put("entity_name", SU.firstUpper(childEntityName));
						lstChildEntity.add(mapRefService);
					}
				}
				mapChildEntity.put("child_entity", lstChildEntity);
				xmlModel.set("child_entity_list", mapChildEntity);

				if (lstParentEntityName != null) {
					for (String parentEntityName : lstParentEntityName) {
						Map<String, Object> mapRefService = new HashMap<String, Object>();
						mapRefService.put("parent_entity_name", SU.firstUpper(parentEntityName));
						lstParentEntity.add(mapRefService);
					}
				}
				mapParentEntity.put("parent_entity", lstParentEntity);
				xmlModel.set("parent_entity_list", mapParentEntity);

				// 生成service接口代码
				IFile serviceInterfaceFile = project.getFile("/src/java/" + projectConfig.getNameSpace().replaceAll("\\.", "/") 
						+ "/" + moduleName + "/service/" + oneGClass.getName() + ".java");
				String templatePath = projectConfig.getServiceTpl();
				JETContext interfaceContext = JETContextHelper.newJETContextHelper(project, moduleName, projectConfig);
				InputStream mergedInterface = GenGFACodeAdapter.mergeJavaCode4Stream(xmlModel, templatePath, 0, interfaceContext,serviceInterfaceFile,whichPlugin);
				if (mergedInterface == null) {
					continue;
				}
				FileUtil.writeFile(mergedInterface, serviceInterfaceFile);
				break;
			}
		}
	}
	
	private void genServiceImplFiles(IProject project,ProjectConfig projectConfig,FrosClass oneGClass,String moduleName,List<XmlModel> springConfiglist,List<XmlModel> dwrConfiglist){
		XmlModel xmlModel = new XmlModel();

		xmlModel.set("entity_name", oneGClass.getName().substring(0, oneGClass.getName().length() - 11));
		xmlModel.set("package_name", projectConfig.getNameSpace() +"." + moduleName + ".service.impl");
		xmlModel.set("entity_path", projectConfig.getNameSpace() +"." + moduleName);
		xmlModel.set("serviceimpl_name", oneGClass.getName());
		if (oneGClass.getParentService() == null || oneGClass.getParentService().length() == 0){
			xmlModel.set("baseservice", "baseService");
		} else {
			xmlModel.set("baseservice", oneGClass.getParentService());
		}
		
		List<AbstractUMLEntityModel> umlModels =list;
		int modelSize = umlModels.size();

		
		List<Map<String, Object>> lstChildEntity = new ArrayList<Map<String, Object>>();
		Map<String, Object> mapChildEntity = new HashMap<String, Object>();
		Map<String, Object> mapRefServices = new HashMap<String, Object>();
		

		//
		List<String> lstParentEntityName = new ArrayList<String>();
		List<Map<String, Object>> lstParentEntity = new ArrayList<Map<String, Object>>();
		Map<String, Object> mapParentEntity = new HashMap<String, Object>();

		for (int i = 0; i < modelSize; i++) {

			if (!(umlModels.get(i) instanceof ClassModel)) {
				continue; // 只对类模型进行处理
			}
			// 初始化实体类
			ClassModel gfaEntityClass = (ClassModel) umlModels.get(i);
			if ((gfaEntityClass.getSimpleName()).equals(oneGClass.getName().substring(0,
					oneGClass.getName().length() - 11))) {
				// source
				xmlModel.set("vertical_extend", gfaEntityClass.isVerticalExtend() ? "true" : "false");
				xmlModel.set("relation", "GENERAL");
				List<AssociationModel> sourceAssociations = (List<AssociationModel>) gfaEntityClass
						.getModelSourceConnections();
				List<ClassModel> lstChildEntityName = new ArrayList<ClassModel>();
				for (AssociationModel oneAssociation : sourceAssociations) {
					if ("1".equals(oneAssociation.getFromMultiplicity()) && "*".equals(oneAssociation.getToMultiplicity())) { // 主表
						ClassModel child = (ClassModel) oneAssociation.getTarget();
						lstChildEntityName.add(child);
					}
					if ("*".equals(oneAssociation.getFromMultiplicity()) && "1".equals(oneAssociation.getToMultiplicity())) { // 子表
						ClassModel parent = (ClassModel) oneAssociation.getTarget();
						// xmlModel.set("parent_entity_name",parent.getSimpleName());
						lstParentEntityName.add(parent.getSimpleName());
					}
					if ("1".equals(oneAssociation.getFromMultiplicity()) && "1".equals(oneAssociation.getToMultiplicity())) {
						ClassModel child = (ClassModel) oneAssociation.getTarget();
						child.setRelation("ONE2ONE");
						lstChildEntityName.add(child);
					}
				}

				// target
				List<AssociationModel> targetAssociations = (List<AssociationModel>) gfaEntityClass
						.getModelTargetConnections();
				for (AssociationModel oneAssociation : targetAssociations) {
					if ("*".equals(oneAssociation.getToMultiplicity()) && "1".equals(oneAssociation.getFromMultiplicity())) { // 子表
						ClassModel parent = (ClassModel) oneAssociation.getSource();
						lstParentEntityName.add(parent.getSimpleName());
					}
					if ("1".equals(oneAssociation.getToMultiplicity()) && "*".equals(oneAssociation.getFromMultiplicity())) { // 主表
						ClassModel child = (ClassModel) oneAssociation.getSource();
						lstChildEntityName.add(child);
					}
					if ("1".equals(oneAssociation.getToMultiplicity()) && "1".equals(oneAssociation.getFromMultiplicity())) {
						ClassModel child = (ClassModel) oneAssociation.getSource();
						child.setRelation("ONE2ONESUB");
						lstChildEntityName.add(child);
					}
				}
				if (lstChildEntityName != null) {
					for (ClassModel childEntity : lstChildEntityName) {
						Map<String, Object> mapRefService = new HashMap<String, Object>();
						mapRefService.put("entity_name", SU.firstUpper(childEntity.getSimpleName()));
						mapRefService.put("vertical_extend", childEntity.isVerticalExtend() ? "true" : "false");
						mapRefService.put("relation", childEntity.getRelation() == null ? "" : childEntity.getRelation());
						lstChildEntity.add(mapRefService);
					}
				}
				mapChildEntity.put("child_entity", lstChildEntity);
				xmlModel.set("child_entity_list", mapChildEntity);

				if (lstParentEntityName != null) {
					for (String parentEntityName : lstParentEntityName) {
						Map<String, Object> mapRefService = new HashMap<String, Object>();
						mapRefService.put("parent_entity_name", SU.firstUpper(parentEntityName));
						lstParentEntity.add(mapRefService);
					}
				}
				mapParentEntity.put("parent_entity", lstParentEntity);
				xmlModel.set("parent_entity_list", mapParentEntity);

				List<Map<String, Object>> lstRefServices = new ArrayList<Map<String, Object>>();
				if (lstChildEntityName != null) {
					for (ClassModel childEntity : lstChildEntityName) {
						Map<String, Object> mapRefService = new HashMap<String, Object>();
						mapRefService.put("service_name", SU.firstUpper(childEntity.getSimpleName() + "Service"));
						mapRefService.put("service_id", SU.firstLower(childEntity.getSimpleName() + "Service"));
						mapRefService.put("relation", childEntity.getRelation() == null ? "" : childEntity.getRelation());
						lstRefServices.add(mapRefService);
					}
				}
				mapRefServices.put("ref_service", lstRefServices);
				xmlModel.set("ref_service_list", mapRefServices);

				// serviceImpl
//				String templatePath = projectConfig.getServiceimplTpl();
				String templatePath = oneGClass.getDeltemplate();
				JETContext serviceImplContext = JETContextHelper.newJETContextHelper(project, moduleName, projectConfig);
				IFile file = project.getFile("/src/java/" + projectConfig.getNameSpace().replaceAll("\\.", "/") 
						+ "/" + moduleName + "/service/impl/" + oneGClass.getName() + ".java");
				// 新生成的文件 
				InputStream mergedImplCode = GenGFACodeAdapter.mergeJavaCode4Stream(xmlModel, templatePath, 0, serviceImplContext,file,whichPlugin);
				if (mergedImplCode == null){
					continue;
				}
				FileUtil.writeFile(mergedImplCode, file);
				break;
			}
		}
		///////////////////////////获取spring.xml和dwr.xml/////////////////////////
		List<AbstractUMLEntityModel> allModel = getRootModel().getChildren();
		int allModelSize = allModel.size();

		for (int i = 0; i < allModelSize; i++) {
			if (!(allModel.get(i) instanceof ClassModel)) {
				continue; // 只对类模型进行处理
			}
			// 初始化实体类
			ClassModel gfaEntityClass = (ClassModel)allModel.get(i);
			if ((gfaEntityClass.getSimpleName()).equals(oneGClass.getName().substring(0,
					oneGClass.getName().length() - 11))) {
				// source
				xmlModel.set("vertical_extend", gfaEntityClass.isVerticalExtend() ? "true" : "false");
				xmlModel.set("relation", "GENERAL");
				List<AssociationModel> sourceAssociations = (List<AssociationModel>) gfaEntityClass
						.getModelSourceConnections();
				List<ClassModel> lstChildEntityName = new ArrayList<ClassModel>();
				for (AssociationModel oneAssociation : sourceAssociations) {
					if ("1".equals(oneAssociation.getFromMultiplicity()) && "*".equals(oneAssociation.getToMultiplicity())) { // 主表
						ClassModel child = (ClassModel) oneAssociation.getTarget();
						lstChildEntityName.add(child);
					}
					if ("*".equals(oneAssociation.getFromMultiplicity()) && "1".equals(oneAssociation.getToMultiplicity())) { // 子表
						ClassModel parent = (ClassModel) oneAssociation.getTarget();
						lstParentEntityName.add(parent.getSimpleName());
					}
					if ("1".equals(oneAssociation.getFromMultiplicity()) && "1".equals(oneAssociation.getToMultiplicity())) {
						ClassModel child = (ClassModel) oneAssociation.getTarget();
						child.setRelation("ONE2ONE");
						lstChildEntityName.add(child);
					}
				}
				// target
				List<AssociationModel> targetAssociations = (List<AssociationModel>) gfaEntityClass
						.getModelTargetConnections();
				for (AssociationModel oneAssociation : targetAssociations) {
					if ("*".equals(oneAssociation.getToMultiplicity()) && "1".equals(oneAssociation.getFromMultiplicity())) { // 子表
						ClassModel parent = (ClassModel) oneAssociation.getSource();
						lstParentEntityName.add(parent.getSimpleName());
					}
					if ("1".equals(oneAssociation.getToMultiplicity()) && "*".equals(oneAssociation.getFromMultiplicity())) { // 主表
						ClassModel child = (ClassModel) oneAssociation.getSource();
						lstChildEntityName.add(child);
					}
					if ("1".equals(oneAssociation.getToMultiplicity()) && "1".equals(oneAssociation.getFromMultiplicity())) {
						ClassModel child = (ClassModel) oneAssociation.getSource();
						child.setRelation("ONE2ONESUB");
						lstChildEntityName.add(child);
					}
				}
				if (lstChildEntityName != null) {
					for (ClassModel childEntity : lstChildEntityName) {
						Map<String, Object> mapRefService = new HashMap<String, Object>();
						mapRefService.put("entity_name", SU.firstUpper(childEntity.getSimpleName()));
						mapRefService.put("vertical_extend", childEntity.isVerticalExtend() ? "true" : "false");
						mapRefService.put("relation", childEntity.getRelation() == null ? "" : childEntity.getRelation());
						lstChildEntity.add(mapRefService);
					}
				}
				mapChildEntity.put("child_entity", lstChildEntity);
				xmlModel.set("child_entity_list", mapChildEntity);

				if (lstParentEntityName != null) {
					for (String parentEntityName : lstParentEntityName) {
						Map<String, Object> mapRefService = new HashMap<String, Object>();
						mapRefService.put("parent_entity_name", SU.firstUpper(parentEntityName));
						lstParentEntity.add(mapRefService);
					}
				}
				mapParentEntity.put("parent_entity", lstParentEntity);
				xmlModel.set("parent_entity_list", mapParentEntity);
				List<Map<String, Object>> lstRefServices = new ArrayList<Map<String, Object>>();
				if (lstChildEntityName != null) {
					for (ClassModel childEntity : lstChildEntityName) {
						Map<String, Object> mapRefService = new HashMap<String, Object>();
						mapRefService.put("service_name", SU.firstUpper(childEntity.getSimpleName() + "Service"));
						mapRefService.put("service_id", SU.firstLower(childEntity.getSimpleName() + "Service"));
						mapRefService.put("relation", childEntity.getRelation() == null ? "" : childEntity.getRelation());
						lstRefServices.add(mapRefService);
					}
				}
				mapRefServices.put("ref_service", lstRefServices);
				xmlModel.set("ref_service_list", mapRefServices);

				// spring config
				if (springConfiglist == null)
					springConfiglist = new ArrayList<XmlModel>();
				springConfiglist.add(xmlModel);
				
				// dwr config
				if (dwrConfiglist == null)
					dwrConfiglist = new ArrayList<XmlModel>();
				dwrConfiglist.add(xmlModel);
				break;
			}
		}
	}
	
	/**
	 * UML模型到G模型的转换
	 * 
	 * @param classModel
	 * 
	 * @author meichenhui
	 * @since 2011-9-1
	 * 
	 */
	private FrosClass umlModel2GModel(ClassModel classModel) {
		// 读取工程配置
		com.gillion.grape.core.utils.ProjectConfig projectConfig = PU.readProjectDesc();
		
		FrosClass gClass = new FrosClass();
		gClass.setGfaType(getClassType(classModel.getName()));
		gClass.setName(classModel.getSimpleName());
		gClass.setSuffix(classModel.getSuffix());
		gClass.setCustomTableName(classModel.getCustomTableName());

		String namespace = projectConfig.getNameSpace();
//		String namespace = ProjectUtil.getEntityNameSpace();
		gClass.setPackageName(namespace + "." + getModuleName());
		gClass.setFlexPackageName(namespace + "." + getModuleName());
		
		gClass.setEnglish(classModel.getEnglish());
		gClass.setSimplifiedChinese(classModel.getSimplifiedChinese());
		gClass.setTraditionalChinese(classModel.getTraditionalChinese());
		
		gClass.setGenerator(classModel.getGenerator());
		gClass.setOptimisticLock(classModel.getOptimisticLock());
		
		// import的内容
		List<String> imports = new ArrayList<String>();
		if (gClass.getPackageName().indexOf(".entity") > 0) {
			imports.add(namespace + ".entity.*");
		}
		gClass.setImports(imports);
		// 视图实体
		gClass.setViewEntity(classModel.isViewEntity());
		// 纵向扩展实体
		gClass.setVerticalExtend(classModel.isVerticalExtend());
		// 基础service
		gClass.setParentService(classModel.getParentService());
		// 设置hbm模板
		if (classModel.getHibernateTemplate() != null){
			gClass.setHbmtemplate(classModel.getHibernateTemplate());
		}
		// 设置DEL模板
		if (classModel.getDeleteTemplate() != null){
			gClass.setDeltemplate(classModel.getDeleteTemplate());
		}
		
		gClass.setVoEntity(classModel.isVoEntity());
		gClass.setCache(classModel.isCache());
		
		for (Object oneElement : classModel.getChildren()) {
			// 属性
			if (oneElement instanceof AttributeModel) {
				AttributeModel oneAttribute = (AttributeModel) oneElement;
				FrosProperty property = new FrosProperty();
				property.setName(oneAttribute.getName());
				property.setType(oneAttribute.getType());
				property.setTypeLenExpression(oneAttribute.getTypeLenExpression());
				property.setDomainType(oneAttribute.getDomainType());
				property.setSimplifiedChinese(oneAttribute.getSimplifiedChinese());
				property.setTraditionalChinese(oneAttribute.getTraditionalChinese());
				property.setEnglish(oneAttribute.getEnglish());
				property.setCustomPropertyName(oneAttribute.getCustomPropertyName());
				property.setLazyM2OType(oneAttribute.getLazyM2O().getName());
				property.setLazyO2MType(oneAttribute.getLazyO2M().getName());
				property.setRelation(oneAttribute.getRelation().name());
				property.setCascade(oneAttribute.getCascade().getName());
				property.setValidateExist(oneAttribute.isValidateExist());
				property.setValidateUnique(oneAttribute.isValidateUnique());
				property.setVerticalExtendField(oneAttribute.isVerticalExtendField());
				gClass.getProperties().add(property);
				continue;
			}
			// 方法
			if (oneElement instanceof OperationModel) {
				OperationModel oneOperation = (OperationModel) oneElement;
				FrosMethod method = new FrosMethod();
				method.setName(oneOperation.getName());
				method.setType(oneOperation.getType());
				for (Object operationChild : oneOperation.getParams()) {
					if (!(operationChild instanceof Argument)) {
						continue;
					}
					Argument oneArg = (Argument) operationChild;
					String argName = oneArg.getName();
					String argType = oneArg.getType();
					method.getParameters().add(argType + " " + argName);
				}
				continue;
			}
		}
		// 关联关系扩展-一对多
		List<Map<String,String>> oneToManyRelations = new ArrayList<Map<String,String>>();
		gClass.setOneToManyRelationExtends(oneToManyRelations);
		for (OneToManyRelation aRelation : classModel.getOneToManyRelations()){
			Map<String,String> oneToManyRelation = new HashMap<String, String>();
			oneToManyRelation.put("name", aRelation.getPropertyName());
			oneToManyRelation.put("lazy", aRelation.getLazyloading().toString().toLowerCase());
			oneToManyRelation.put("fk-prop-name", aRelation.getForeignKeyName());
			oneToManyRelation.put("column", aRelation.getColumn());
			oneToManyRelation.put("class", aRelation.getChildEntity());
			oneToManyRelations.add(oneToManyRelation);
		}
		// 关联关系扩展-多对一
		List<Map<String,String>> manyToOneRelations = new ArrayList<Map<String,String>>();
		gClass.setManyToOneRelationExtends(manyToOneRelations);
		for (ManyToOneRelation aRelation : classModel.getManyToOneRelations()){
			Map<String,String> manyToOneRelation = new HashMap<String, String>();
			manyToOneRelation.put("name", aRelation.getPropertyName());
			manyToOneRelation.put("class", aRelation.getParentClass());
			manyToOneRelation.put("column", aRelation.getColumn());
			manyToOneRelation.put("lazy", aRelation.getLazyloading().toString().toLowerCase());
			manyToOneRelations.add(manyToOneRelation);
		}
		return gClass;
	}
	
	
	/**
	 * 判断实体模型是什么类型的类
	 * @param className
	 * @return
	 *
	 * @author meichenhui
	 * @since 2011-9-1
	 *
	 */
	public GFAClassType getClassType(String className){
		String[] nameSplited = className.split("\\.");
		if ("entity".equals(nameSplited[nameSplited.length - 2])) {
			return GFAClassType.Entity;
		}
		if ("domain".equals(nameSplited[nameSplited.length - 2])) {
			return GFAClassType.EntityDomain;
		}
		if ("impl".equals(nameSplited[nameSplited.length - 2])) {
			return GFAClassType.ServiceImpl;
		}
		if ("service".equals(nameSplited[nameSplited.length - 2])) {
			return GFAClassType.Service;
		}
		return GFAClassType.Other;
	}
	
	/**
	 * UML接口模型转换为GClass对象
	 * 
	 * @param interfaceModel
	 * @return
	 * 
	 * @author meichenhui
	 * @since 2011-9-1
	 * 
	 */
	private FrosClass interfaceModel2GInterface(InterfaceModel interfaceModel) {
		// 读取工程配置
		com.gillion.grape.core.utils.ProjectConfig projectConfig = PU.readProjectDesc();
		
		FrosClass gClass = new FrosClass();
		gClass.setGfaType(GFAClassType.Service);
		gClass.setInterface(true);
		gClass.setName(interfaceModel.getSimpleName());
		String namespace = projectConfig.getNameSpace();
		gClass.setPackageName(namespace + "." + getModuleName());
		gClass.setFlexPackageName(namespace + "." + getModuleName());
		// import的内容
		List<String> imports = new ArrayList<String>();
		if (gClass.getPackageName().indexOf(".entity") > 0) {
			imports.add(namespace + ".entity.*");
		}
		gClass.setImports(imports);
		gClass.setViewEntity(interfaceModel.isViewEntity());
		for (Object oneElement : interfaceModel.getChildren()) {
			// 方法
			if (oneElement instanceof OperationModel) {
				OperationModel oneOperation = (OperationModel) oneElement;
				FrosMethod method = new FrosMethod();
				method.setName(oneOperation.getName());
				method.setType(oneOperation.getType());
				for (Object operationChild : oneOperation.getParams()) {
					if (!(operationChild instanceof Argument)) {
						continue;
					}
					Argument oneArg = (Argument) operationChild;
					String argName = oneArg.getName();
					String argType = oneArg.getType();
					method.getParameters().add(argType + " " + argName);
					// gClass.getMethods().
				}
				continue;
			}
		}
		return gClass;
	}
	
	private void genValidateUniqueConfig(
			List<Map<String, Object>> properties_validate_unique,
			ProjectConfig projectConfig, IProject project, String moduleName) {
		JETContext context = JETContextHelper.newJETContextHelper(project, moduleName, projectConfig);
		IFile propertiesFile = project.getFile("/src/resource/config/" + "entity_unique_config.properties");
		InputStream mergedProperties = GenGFACodeAdapter.mergeProperties4Stream(properties_validate_unique, projectConfig.getEntityValidateUniqueTpl(), 0, context, propertiesFile,whichPlugin);
		FileUtil.writeFile(mergedProperties,propertiesFile);
	}

	private void genValidateExistConfig(
			List<Map<String, Object>> properties_validate_exist,
			ProjectConfig projectConfig, IProject project, String moduleName) {
		// 生成本模块的配置
		JETContext context = JETContextHelper.newJETContextHelper(project, moduleName, projectConfig);
		IFile propertiesFile = project.getFile("/src/resource/config/" + "entity_exist_config.properties");
		InputStream mergedProperties = GenGFACodeAdapter.mergeProperties4Stream(properties_validate_exist, projectConfig.getEntityValidateExistTpl(), 0, context, propertiesFile,whichPlugin);
		FileUtil.writeFile(mergedProperties,propertiesFile);
	}

}
